/*
 * @Author: your name
 * @Date: 2021-08-29 21:41:03
 * @LastEditTime: 2021-08-29 21:44:12
 * @LastEditors: Please set LastEditors
 * @Description: In User Settings Edit
 * @FilePath: \miniDataBase\src\common.c
 */
#include "common.h"
#include <stdlib.h>
#include <string.h>
#include <stdio.h>

/**
 * 打印控制台的头部
 */
void print_prompt()
{
    printf("db > ");
}

ssize_t getline(char **lineptr, size_t *n, FILE *stream)
{
    char *buf = *lineptr;
    ssize_t c, i = 0; //i来记录字符串长度，c来存储字符
    if (buf == NULL || *n == 0)
    {
        *lineptr = (char *)malloc(10);
        buf = *lineptr;
        *n = 10;
    }
    //buf为或n为0时动态为期分配空间
    while ((c = fgetc(stream)) != '\n')
    {
        if (c == EOF)
            return -1;
        if (i < *n - 2) //留2个空间给\n和\0
        {
            *(buf + i++) = c;
        }
        else
        {
            *n = *n + 10;
            buf = (char *)realloc(buf, *n); //空间不足时，重新进行分配
            *(buf + i++) = c;
        }
    }
    *(buf + i++) = '\n';
    *(buf + i) = '\0';
    return i;
}

InputBuffer *new_input_buffer()
{
    InputBuffer *input_buffer = (InputBuffer *)malloc(sizeof(InputBuffer));
    // 初始化InputBuffer结构体成员变量的值
    input_buffer->buffer = NULL;
    input_buffer->buffer_length = 0;
    input_buffer->input_length = 0;
    return input_buffer;
}

/**
 * 读取控制台输入的内容
 * @param input_buffer  控制台输入信息
 */
void read_input(InputBuffer *input_buffer)
{
    ssize_t bytes_read = getline(&(input_buffer->buffer), &(input_buffer->input_length), stdin);
    // 如果读取的字节小于0则表示读取失败
    if (bytes_read < 0)
    {
        printf("Error reading input\n");
        exit(EXIT_FAILURE); // 退出
    }
    input_buffer->input_length = bytes_read - 1; // -1操作是为了去掉换行符\n
    input_buffer->buffer[bytes_read - 1] = 0;
}

/**
 * 释放分配给InputBuffer *的内存和buffer中元素各自的结构
 * @param input_buffer
 */
void close_input_buffer(InputBuffer *input_buffer)
{
    free(input_buffer->buffer);
    free(input_buffer);
}

PrepareResult prepare_insert(InputBuffer *input_buffer, Statement *statement)
{
    statement->type = STATEMENT_INSERT;
    char *keyword = strtok(input_buffer->buffer, " ");
    char *id_string = strtok(NULL, " ");
    char *username = strtok(NULL, " ");
    char *email = strtok(NULL, " ");

    // 判断Row结构体成员变量中只要有一个为NULL则就是语法错误
    if (id_string == NULL || username == NULL || email == NULL)
    {
        return PERPARE_SYNTAX_ERROR;
    }
    int id = atoi(id_string);
    if (id < 0)
    {
        return PREPARE_NEGATIVE_ID;
    }

    if (strlen(username) > COLUMN_USERNAME_SIZE)
    {
        return PREPARE_STRING_TOO_LONG;
    }
    if (strlen(email) > COLUMN_EMAIL_SIZE)
    {
        return PREPARE_STRING_TOO_LONG;
    }

    statement->row_to_insert.id = id;
    strcpy(statement->row_to_insert.username, username);
    strcpy(statement->row_to_insert.email, email);

    return PERPARE_SUCCESS;
}
